
# 从src.Core.Interfaces模块导入ICodeCompiler接口类
from src.Core.Interfaces import ICodeCompiler


class Py3FunctionCompiler(ICodeCompiler):
    """
    该类继承自ICodeCompiler接口，用于将字符串编译为Python函数。
    """

    def __init__(self, fooName=None, *args, **kwargs):
        """
        初始化Py3FunctionCompiler类的实例。

        :param fooName: 要创建的函数的名称，必须为字符串类型。
        :param args: 传递给父类构造函数的可变位置参数。
        :param kwargs: 传递给父类构造函数的可变关键字参数。
        """
        # 调用父类的构造函数
        super(Py3FunctionCompiler, self).__init__(*args, **kwargs)
        # 断言fooName是字符串类型
        assert isinstance(fooName, str)
        # 存储函数名称
        self._fooName = fooName

    def compile(self, code):
        """
        将传入的代码包装成一个Python函数定义并编译。

        :param code: 要包装的代码，类型为字符串。
        :returns: 编译后的函数对象。
        :rtype: function
        """
        # 构建函数定义的头部
        foo = "def {}(self):".format(self._fooName)
        # 将传入的代码按行分割，并过滤掉空行
        lines = [i for i in code.split("\n") if len(i) > 0]
        # 遍历每一行代码，将其添加到函数定义中，并添加缩进
        for line in lines:
            foo += "\n\t{}".format(line)
        # 如果传入的代码为空，则添加一个pass语句
        if len(lines) == 0:
            foo += "\n\tpass"
        # 使用Python内置的compile函数将函数定义字符串编译为代码对象
        codeObject = compile(foo, "PyFlowCodeCompiler", "exec")
        # 用于存储编译后的命名空间
        mem = {}
        # 执行编译后的代码对象
        exec(codeObject, mem)
        # 返回编译后的函数对象
        return mem[self._fooName]


class Py3CodeCompiler(ICodeCompiler):
    """
    该类继承自ICodeCompiler接口，是一个通用的Python代码编译器。
    """

    def __init__(self):
        """
        初始化Py3CodeCompiler类的实例。
        """
        # 调用父类的构造函数
        super(Py3CodeCompiler, self).__init__()

    def compile(self, code, moduleName="PyFlowCodeCompiler", scope=None):
        """
        评估传入的Python代码字符串。

        该方法通常被Python节点使用。

        :param code: 任意Python代码，类型为字符串。
        :param moduleName: 用于运行时错误消息的模块名称，默认为"PyFlowCodeCompiler"。
        :param scope: 存储符号的字典，默认为None，若为None则创建一个空字典。
        :return: 包含执行后符号的字典。
        """
        # 如果scope为None，则创建一个空字典
        if scope is None:
            scope = {}
        # 使用Python内置的compile函数将代码字符串编译为代码对象
        codeObject = compile(code, moduleName, "exec")
        # 执行编译后的代码对象，并将符号存储在scope中
        exec(codeObject, scope)
        # 返回包含执行后符号的字典
        return scope